package com.duoduo.common.exception;

import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.duoduo.common.response.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * @author duoduo
 * @version 1.0
 * <p>全局异常处理</p>
 */
@RestControllerAdvice
@Slf4j
public class ServiceExceptionHandler {

    /**
     * 处理token异常
     */
    @ExceptionHandler({SignatureVerificationException.class, AlgorithmMismatchException.class, JWTDecodeException.class})
    public Result tokenErrorException() {
        StackTraceElement element = Thread.currentThread().getStackTrace()[0];
        Result result = Result.builder()
                .code("A0200")
                .message("登录异常")
                .userTip("无效的token！")
                .stackTrace(element.getClassName() + "" + element.getLineNumber())
                .build();
        log.error("无效的token");
        return result;
    }

    /**
     * 处理token异常
     */
    @ExceptionHandler({TokenExpiredException.class})
    public Result tokenExpiredException(TokenExpiredException e) {
        Result result = Result.builder()
                .code("A0230")
                .userTip("登录已过期")
                .message("token超时！")
                .stackTrace(e.getStackTrace()[0].toString())
                .build();
        log.error("用户token超时");
        return result;
    }

    /**
     *  处理方法参数无效异常
     * @ClassName ServiceExceptionHandler
     * @Date 2022/11/18  14:47
     * @Version 1.0
     */
    @ExceptionHandler({MethodArgumentNotValidException.class})
    public Result allMethodArgumentNotValidException(MethodArgumentNotValidException e){
        System.out.println("MethodArgumentNotValidException = " + e.getFieldError().getDefaultMessage());
        Result result = Result.builder()
                .code("A0400")
                .userTip("请求参数错误")
                .message(e.getFieldError().getDefaultMessage())
                .stackTrace(e.getStackTrace()[0].toString())
                .build();
        log.error(e.getMessage());
        e.printStackTrace();
        return result;
    }

    /**
     *  处理Http消息不可读异常
     * @ClassName ServiceExceptionHandler
     * @Date 2022/11/18  14:47
     * @Version 1.0
     */
    @ExceptionHandler({HttpMessageNotReadableException.class})
    public Result allHttpMessageNotReadableException(HttpMessageNotReadableException e) {
        System.out.println("e = " + e);
        Result result = Result.builder()
                .code("A0402")
                .userTip("无效的用户输入")
                .message("请求方式或者请求参数不是指定的类型！")
                .stackTrace(e.getStackTrace()[0].toString())
                .build();
        log.error(e.getMessage());
        e.printStackTrace();
        return result;
    }

    /**
     * 处理所有RuntimeException异常
     */
    @ExceptionHandler({RuntimeException.class})
    public Result allException(RuntimeException e) {
        System.out.println("RuntimeException = " + e);
        Result result = null;
        if (e.getMessage() != null && e.getMessage().contains("#-#")) {
            String[] split = e.getMessage().split("#-#");
            result = Result.builder()
                    .code(split[0])
                    .userTip(split[1])
                    .message("用户登录异常")
                    .stackTrace(e.getStackTrace()[0].toString())
                    .build();
            log.error(e.getMessage());
            e.printStackTrace();
        }else {
            result = Result.builder()
                    .code("B0001")
                    .userTip("系统执行出错")
                    .message(e.toString())
                    .stackTrace(e.getStackTrace()[0].toString())
                    .build();
            log.error(e.getMessage());
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 处理所有Exception异常
     */
    @ExceptionHandler({Exception.class})
    public Result ResultAllException(Exception e) {
        System.out.println("Exception = " + e);
        Result result = Result.builder()
                .code("B0001")
                .userTip("系统执行出错")
                .message(e.toString())
                .stackTrace(e.getStackTrace()[0].toString())
                .build();
        log.error(e.getMessage());
        e.printStackTrace();
        return result;
    }

}
